<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller
{

    protected $__enable_sign_check = ENVIRONMENT === 'development' ? false : true;
    protected $__enable_login_check = true;
    protected $__enable_common_check = true;
    public $request_array = [];
    public $response_array = [];
    public $_uid = null;
    public $userinfo;
    public $os;
    public $sv;

    public function __construct()
    {
        parent::__construct();
        date_default_timezone_set('Asia/Shanghai');

        $_POST += $_GET;
        $this->request_array = $_POST;
        $this->response_array = array(
            'errorMessage' => STATUS_OK,
            'resultData' => array(),
        );

        //签名 校验
        // $this->__checkSign($this->request_array);
        //设置公参属性
        $this->__set_common_params($this->request_array);
        //登录校验
        $this->__check_user($this->request_array['userId'] ?? 0, $this->request_array['token'] ?? '');
        //常量设置
        $this->__set_global_const();
    }


    /**
     * json 数据返回
     *
     * @param int    $errno
     * @param array  $data
     * @param string $msg
     * @param int    $status_header
     *
     * @return void
     */
    protected function renderJson(int $errno = 0, $data = array(), string $msg = '', int $status_header = 200)
    {
        if (!$msg) {
            $msg_map = $this->config->item('msg_map');
            $msg_info = $msg_map[$errno] ?? $msg_map[SYSTEM_ERR] ?? 'system error';
            $msg_en = $msg_info['en'];
            $msg_cn = $msg_info['cn'];
        } else {
            $msg_en = $msg_cn = $msg;
        }
        if ( ! $msg)
        {
            if (is_string($data))
            {
                $msg_en = $msg_cn = $data;
            }
        }
        if (!$data) {
            $data = [];
        }
        if ($errno) {
            log_message('error', 'render err. ' .
                sprintf('status_header:[%s] uri:[%s] data:[%s] errno:[%s] msg:[%s]',
                    $status_header, parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), json_encode($_REQUEST), $errno,
                    $msg_cn));
        }
        $json = $this->output
            ->set_status_header($status_header)
            ->set_content_type('application/json', 'utf-8')
            ->set_output(json_encode([
                'errorCode'     => $errno,
                'resultData'    => $data,
                'errorMessage'  => $msg_en,
            ]));
        if ( null !== $this->input->get_request_header('X-SHOW-ERROR'))
        {
            $json->set_header('X-SHOW-ERROR: 1');
        }
        $json->_display();
        exit();
    }


    /**
     * 签名校验
     *
     * @param $arrInput
     *
     * @return void
     */
    private function __checkSign($arrInput)
    {
        if (!$this->__enable_sign_check) {
            return;
        }
        $sign = @$arrInput['sign'];
        unset($arrInput['sign']);
        $getSign = $this->__getSign($arrInput);
        if ($sign === $getSign) {
            return;
        }
        log_message('error', 'sign err. server sign:[' . $getSign . ']');
        $this->renderJson(SIGN_ERR, [], '', 403);
    }


    /**
     * 获取签名
     *
     * @param $arrInput
     *
     * @return string
     */
    private function __getSign($arrInput)
    {
        $str = $this->__getQueryString($arrInput);
        $str = substr($str, 0, strlen($str) - 1);
        return md5(sha1($str));
    }


    /**
     * 签名字符串
     *
     * @param array  $arrInput
     * @param string $superKey
     *
     * @return string
     */
    private function __getQueryString($arrInput, $superKey = '')
    {
        $str = '';
        ksort($arrInput);
        foreach ($arrInput as $key => $value) {
            if ($superKey != '') {
                $key = $superKey . '[' . $key . ']';
            }
            if (is_array($value)) {
                $str .= $this->__getQueryString($value, $key);
            } else {
                $str .= $key . '=' . $value . '&';
            }
        }
        return $str;
    }


    /**
     * 公参设置
     *
     * @param $request
     *
     * @return void
     */
    private function __set_common_params(&$request)
    {
        if (!$this->__enable_common_check) {
            return;
        }
        $this->os = $request['os'] ?? '';
        $this->sv = $request['sv'] ?? '';
    }


    /**
     * 用户登录校验
     *
     * @param $userid
     *
     * @return void
     */
    private function __check_user($userid, $token)
    {
        if (!$this->__enable_login_check && empty($userid) && empty($token)) {
            return null;
        }
        $this->load->model('services/user_service', 'user_service');
        $err = null;
        $this->user_service->checkUserLogin($userid, $token, $err);
        if ( ! is_null($err))
        {
            $this->renderJson($err['errorCode'], [], $err['errorMessage']);
        }
        $this->_uid = $userid;
        $this->__set_user_info($this->_uid);
    }

    private function __set_user_info($user_id)
    {
        $this->userinfo = $this->user_service->getUserInfoById($user_id);
    }


    /**
     * 常量设置
     */
    private function __set_global_const()
    {
        $pushkey = $this->request_array['pushkey'] ?? '';
        $channel = $this->request_array['channel'] ?? '';
    }

    /**
     * iOS审核检查
     *
     * @param $pushkey
     *
     * @return bool
     */
    private function __get_ios_check($pushkey)
    {
        if ($this->os != 'ios') {
            return false;
        }
        if (!$pushkey) {
            $pushkey = 'normal';
        }
        if (IOS_VERSION[$pushkey] != $this->sv) {
            return false;
        }
        return true;
    }

    /**
     * Android 审核检查
     *
     * @param $channel
     *
     * @return bool
     */
    private function __get_android_check($channel) {
        if ( $this->os != 'android') {
            return false;
        }
        if ( ANDROID_CHECK_INFO['channel'][$channel] != $this->sv) {
            return false;
        }
        return true;
    }
}
